﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CharacterCreation.Data.Annotations;

namespace CharacterCreation.Data.QueryBuilders {
    public class InsertBuilder {
        public static string InsertQuery<T>(T entity) {
            TableAttribute tableAttribute = TableBuilder.GetTableAttribute<T>();
            StringBuilder builder = new StringBuilder();
            StringBuilder columnDefinition = new StringBuilder();
            StringBuilder valueDefinitions = new StringBuilder();

            foreach (var pInfo in typeof(T).GetProperties()) {

                // skip if this item needs to be ignored
                if (pInfo.GetCustomAttributes(typeof(IgnoreAttribute), false).FirstOrDefault() != null) continue;

                // insert the comma after the different definitions
                if (!string.IsNullOrWhiteSpace(columnDefinition.ToString())) columnDefinition.Append("," + Environment.NewLine);
                if (!string.IsNullOrWhiteSpace(valueDefinitions.ToString())) valueDefinitions.Append("," + Environment.NewLine);

                columnDefinition.AppendFormat("[{0}]", pInfo.Name);
                object result = string.Empty;
                if (pInfo.PropertyType.ToString() == "System.DateTime") 
                    result = ((DateTime)pInfo.GetValue(entity, null)).ToString("yyyy-MM-dd HH:mm:ss");
                else
                    result = pInfo.GetValue(entity, null);
                if (!appendQuotes(pInfo)) valueDefinitions.AppendFormat("{0}", result);
                else valueDefinitions.AppendFormat("'{0}'", result != null ? result.ToString().Replace("'", "''") : result);
            }

            builder.AppendFormat("insert into {0} ( {1} ) values ( {2} );", tableAttribute.TableName, columnDefinition, valueDefinitions);
            return builder.ToString();
        }

        public static string InsertQuery<T>(IEnumerable<T> entities)
        {
            StringBuilder builder = new StringBuilder();
            foreach (var entity in entities)
            {
                builder.Append(InsertBuilder.InsertQuery(entity));
            }
            return builder.ToString();
        }

        private static bool appendQuotes(System.Reflection.PropertyInfo pInfo) {
            switch (pInfo.PropertyType.ToString()) {
                case "System.String":
                    return true;
                case "System.Int16":
                case "System.Int32":
                case "System.Int64":
                    return false;
                case "System.Boolean":
                    return false;
                case "System.DateTime":
                    return true;
                case "System.Guid":
                    return true;
                default:
                    return true;
            }
        }


        
    }
}
